package com.seafood.controller;

import com.seafood.common.Result;
import com.seafood.dto.GeocodingRequestDTO;
import com.seafood.dto.GeocodingResponseDTO;
import com.seafood.dto.LocationAddressDTO;
import com.seafood.dto.ReverseGeocodingRequestDTO;
import com.seafood.service.MapService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 地图服务控制器
 * 
 * @author System
 * @since 2024-01-01
 */
@Slf4j
@RestController
@RequestMapping("/api/map")
@RequiredArgsConstructor
@Tag(name = "地图服务", description = "地图服务相关接口")
public class MapController {

    private final MapService mapService;

    @Operation(summary = "地理编码")
    @PostMapping("/geocoding")
    public Result<GeocodingResponseDTO> geocoding(@Valid @RequestBody GeocodingRequestDTO requestDTO) {
        log.info("地理编码请求: {}", requestDTO.getAddress());
        
        try {
            GeocodingResponseDTO result = mapService.geocoding(requestDTO);
            return Result.success("地理编码成功", result);
        } catch (Exception e) {
            log.error("地理编码失败", e);
            return Result.error("地理编码失败：" + e.getMessage());
        }
    }

    @Operation(summary = "逆地理编码")
    @PostMapping("/reverse-geocoding")
    public Result<GeocodingResponseDTO> reverseGeocoding(@Valid @RequestBody ReverseGeocodingRequestDTO requestDTO) {
        log.info("逆地理编码请求: lat={}, lon={}", requestDTO.getLatitude(), requestDTO.getLongitude());
        
        try {
            GeocodingResponseDTO result = mapService.reverseGeocoding(requestDTO);
            return Result.success("逆地理编码成功", result);
        } catch (Exception e) {
            log.error("逆地理编码失败", e);
            return Result.error("逆地理编码失败：" + e.getMessage());
        }
    }

    @Operation(summary = "计算两点间距离")
    @GetMapping("/distance")
    public Result<Map<String, Object>> calculateDistance(
            @RequestParam BigDecimal lat1,
            @RequestParam BigDecimal lon1,
            @RequestParam BigDecimal lat2,
            @RequestParam BigDecimal lon2) {
        log.info("计算距离: 起点({}, {}), 终点({}, {})", lat1, lon1, lat2, lon2);
        
        try {
            Double distance = mapService.calculateDistance(lat1, lon1, lat2, lon2);
            Map<String, Object> result = new HashMap<>();
            result.put("distance", distance);
            result.put("unit", "kilometers");
            
            Map<String, Object> startPoint = new HashMap<>();
            startPoint.put("latitude", lat1);
            startPoint.put("longitude", lon1);
            result.put("startPoint", startPoint);
            
            Map<String, Object> endPoint = new HashMap<>();
            endPoint.put("latitude", lat2);
            endPoint.put("longitude", lon2);
            result.put("endPoint", endPoint);
            
            return Result.success("距离计算成功", result);
        } catch (Exception e) {
            log.error("计算距离失败", e);
            return Result.error("计算距离失败：" + e.getMessage());
        }
    }

    @Operation(summary = "路径规划")
    @GetMapping("/route")
    public Result<Map<String, Object>> planRoute(
            @RequestParam BigDecimal startLat,
            @RequestParam BigDecimal startLon,
            @RequestParam BigDecimal endLat,
            @RequestParam BigDecimal endLon,
            @RequestParam(defaultValue = "driving") String routeType) {
        log.info("路径规划: 起点({}, {}), 终点({}, {}), 类型: {}", 
                startLat, startLon, endLat, endLon, routeType);
        
        try {
            // 使用多点路径规划方法
            LocationAddressDTO startPoint = new LocationAddressDTO();
            startPoint.setLatitude(startLat);
            startPoint.setLongitude(startLon);
            
            LocationAddressDTO endPoint = new LocationAddressDTO();
            endPoint.setLatitude(endLat);
            endPoint.setLongitude(endLon);
            
            List<LocationAddressDTO> waypoints = new ArrayList<>();
            waypoints.add(startPoint);
            waypoints.add(endPoint);
            Map<String, Object> result = mapService.calculateRoute(waypoints, routeType);
            return Result.success("路径规划成功", result);
        } catch (Exception e) {
            log.error("路径规划失败", e);
            return Result.error("路径规划失败：" + e.getMessage());
        }
    }

    @Operation(summary = "坐标转换")
    @GetMapping("/coordinate/convert")
    public Result<Map<String, Object>> convertCoordinate(
            @RequestParam BigDecimal latitude,
            @RequestParam BigDecimal longitude,
            @RequestParam String fromSystem,
            @RequestParam String toSystem) {
        log.info("坐标转换: 坐标({}, {}), 从{}转换到{}", latitude, longitude, fromSystem, toSystem);
        
        try {
            Map<String, BigDecimal> coords = mapService.convertCoordinates(latitude, longitude, fromSystem, toSystem);
            Map<String, Object> result = new HashMap<>();
            
            Map<String, Object> originalCoords = new HashMap<>();
            originalCoords.put("latitude", latitude);
            originalCoords.put("longitude", longitude);
            originalCoords.put("system", fromSystem);
            result.put("originalCoordinates", originalCoords);
            
            Map<String, Object> convertedCoords = new HashMap<>();
            convertedCoords.put("latitude", coords.get("latitude"));
            convertedCoords.put("longitude", coords.get("longitude"));
            convertedCoords.put("system", toSystem);
            result.put("convertedCoordinates", convertedCoords);
            
            return Result.success("坐标转换成功", result);
        } catch (Exception e) {
            log.error("坐标转换失败", e);
            return Result.error("坐标转换失败：" + e.getMessage());
        }
    }

    @Operation(summary = "地图服务状态检查")
    @GetMapping("/status")
    public Result<Map<String, Object>> getServiceStatus() {
        log.info("检查地图服务状态");
        
        try {
            Map<String, Object> result = new HashMap<>();
            result.put("serviceName", "地图服务");
            result.put("status", "online");
            result.put("version", "1.0.0");
            
            List<String> features = new ArrayList<>();
            features.add("地理编码");
            features.add("逆地理编码");
            features.add("距离计算");
            features.add("路径规划");
            features.add("坐标转换");
            result.put("supportedFeatures", features);
            
            return Result.success("服务状态获取成功", result);
        } catch (Exception e) {
            log.error("获取服务状态失败", e);
            return Result.error("获取服务状态失败：" + e.getMessage());
        }
    }
}